﻿// UnderWaterComAlogrithm.cpp : 定义 DLL 的导出函数。
//

#include "pch.h"
#include "framework.h"
#include "UnderWaterComAlogrithm.h"

#include "scfun.h"
#include <iostream>
#include <chrono> // 用于计时
#include <string>

using namespace std;


void UnderWaterComAlogrithm::IPP_Va_Init()
{
    Syn_Flag_1 = 0;
    Syn_PosFirst_1 = -1;
    Syn_FlagFirst_1 = 0;
    *Syn_StepCnt_1 = 0;
    ippsZero_8u(Syn_DataCacheCnt_1, sizeof(Ipp8u));
    ippsZero_32fc(Syn_DataCache_1, g_Syn_BufCnt * 30);
    ippsZero_32fc(Syn_DataCachePrmy_1, g_Syn_BufCnt * 30);
    ippsZero_32fc(Sig_blk_1, g_Syn_NFFT_RAW);
    ippsZero_32f(Syn_SigIn_1, g_Syn_BufCnt);
    ippsZero_32f(Syn_SigRec_1, g_InfoSamPointTotalSyn);


    Syn_Flag_2 = 0;
    Syn_PosFirst_2 = -1;
    Syn_FlagFirst_2 = 0;
    *Syn_StepCnt_2 = 0;
    ippsZero_8u(Syn_DataCacheCnt_2, sizeof(Ipp8u));
    ippsZero_32fc(Syn_DataCache_2, g_Syn_BufCnt * 30);
    ippsZero_32fc(Syn_DataCachePrmy_2, g_Syn_BufCnt * 30);
    ippsZero_32fc(Sig_blk_2, g_Syn_NFFT_RAW);
    ippsZero_32f(Syn_SigIn_2, g_Syn_BufCnt);
    ippsZero_32f(Syn_SigRec_2, g_InfoSamPointTotalSyn);


    Syn_Flag_3 = 0;
    Syn_PosFirst_3 = -1;
    Syn_FlagFirst_3 = 0;
    *Syn_StepCnt_3 = 0;
    ippsZero_8u(Syn_DataCacheCnt_3, sizeof(Ipp8u));
    ippsZero_32fc(Syn_DataCache_3, g_Syn_BufCnt * 30);
    ippsZero_32fc(Syn_DataCachePrmy_3, g_Syn_BufCnt * 30);
    ippsZero_32fc(Sig_blk_3, g_Syn_NFFT_RAW);
    ippsZero_32f(Syn_SigIn_3, g_Syn_BufCnt);
    ippsZero_32f(Syn_SigRec_3, g_InfoSamPointTotalSyn);



    Syn_Flag_4 = 0;
    Syn_PosFirst_4 = -1;
    Syn_FlagFirst_4 = 0;
    *Syn_StepCnt_4 = 0;
    ippsZero_8u(Syn_DataCacheCnt_4, sizeof(Ipp8u));
    ippsZero_32fc(Syn_DataCache_4, g_Syn_BufCnt * 30);
    ippsZero_32fc(Syn_DataCachePrmy_4, g_Syn_BufCnt * 30);
    ippsZero_32fc(Sig_blk_4, g_Syn_NFFT_RAW);
    ippsZero_32f(Syn_SigIn_4, g_Syn_BufCnt);
    ippsZero_32f(Syn_SigRec_4, g_InfoSamPointTotalSyn);

    OutputDebugString(L"进入了频域的初始化函数");

}

void UnderWaterComAlogrithm::SF_IPP_Va_Init()
{
    SF_Syn_Flag_1 = 0;
    SF_Syn_PosFirst_1 = -1;
    SF_Syn_FlagFirst_1 = 0;
    ippsZero_8u(SF_Syn_StepCnt_1, sizeof(Ipp8u));
    ippsZero_8u(SF_Syn_DataCacheCnt_1, sizeof(Ipp8u));
    ippsZero_32fc(SF_Syn_DataCache_1, SF_g_Syn_BufCnt * 30);
    ippsZero_32fc(SF_Syn_DataCachePrmy_1, SF_g_Syn_BufCnt * 30);
    ippsZero_32fc(SF_Sig_blk_1, SF_g_Syn_NFFT_RAW);
    ippsZero_32f(SF_Syn_SigIn_1, SF_g_Syn_BufCnt);
    ippsZero_32f(SF_Syn_SigRec_1, SF_g_InfoSamPointTotalSyn);

    SF_Syn_Flag_2 = 0;
    SF_Syn_PosFirst_2 = -1;
    SF_Syn_FlagFirst_2 = 0;
    ippsZero_8u(SF_Syn_StepCnt_2, sizeof(Ipp8u));
    ippsZero_8u(SF_Syn_DataCacheCnt_2, sizeof(Ipp8u));
    ippsZero_32fc(SF_Syn_DataCache_2, SF_g_Syn_BufCnt * 40);
    ippsZero_32fc(SF_Syn_DataCachePrmy_2, SF_g_Syn_BufCnt * 40);
    ippsZero_32fc(SF_Sig_blk_2, SF_g_Syn_NFFT_RAW);
    ippsZero_32f(SF_Syn_SigIn_2, SF_g_Syn_BufCnt);
    ippsZero_32f(SF_Syn_SigRec_2, SF_g_InfoSamPointTotalSyn);

    SF_Syn_Flag_3 = 0;
    SF_Syn_PosFirst_3 = -1;
    SF_Syn_FlagFirst_3 = 0;
    ippsZero_8u(SF_Syn_StepCnt_3, sizeof(Ipp8u));
    ippsZero_8u(SF_Syn_DataCacheCnt_3, sizeof(Ipp8u));
    ippsZero_32fc(SF_Syn_DataCache_3, SF_g_Syn_BufCnt * 40);
    ippsZero_32fc(SF_Syn_DataCachePrmy_3, SF_g_Syn_BufCnt * 40);
    ippsZero_32fc(SF_Sig_blk_3, SF_g_Syn_NFFT_RAW);
    ippsZero_32f(SF_Syn_SigIn_3, SF_g_Syn_BufCnt);
    ippsZero_32f(SF_Syn_SigRec_3, SF_g_InfoSamPointTotalSyn);

    SF_Syn_Flag_4 = 0;
    SF_Syn_PosFirst_4 = -1;
    SF_Syn_FlagFirst_4 = 0;
    ippsZero_8u(SF_Syn_StepCnt_4, sizeof(Ipp8u));
    ippsZero_8u(SF_Syn_DataCacheCnt_4, sizeof(Ipp8u));
    ippsZero_32fc(SF_Syn_DataCache_4, SF_g_Syn_BufCnt * 30);
    ippsZero_32fc(SF_Syn_DataCachePrmy_4, SF_g_Syn_BufCnt * 30);
    ippsZero_32fc(SF_Sig_blk_4, SF_g_Syn_NFFT_RAW);
    ippsZero_32f(SF_Syn_SigIn_4, SF_g_Syn_BufCnt);
    ippsZero_32f(SF_Syn_SigRec_4, SF_g_InfoSamPointTotalSyn);

    OutputDebugString(L"进入了短帧的初始化函数");

}

void UnderWaterComAlogrithm::MASS_Init()
{
    *Syn_StepCnt_MASS = 0;
    *Syn_DataCacheCnt_MASS = 0;
    ippsZero_32fc(Syn_DataCache_MASS, MA_g_Syn_BufCnt * 30);
    ippsZero_32fc(Syn_DataCachePrmy_MASS, MA_g_Syn_BufCnt * 30);
    ippsZero_32fc(Sig_blk_MASS, MA_g_Syn_NFFT_RAW);
    ippsZero_32f(Syn_SigIn_MASS, MA_g_Syn_BufCnt);
    ippsZero_32f(Syn_SigRec_MASS, MA_g_InfoSamPointTotalSyn);
    Syn_PosFirst_MASS = -1;
    Syn_FlagFirst_MASS = 0;
    Syn_Flag_MASS = 0;

    OutputDebugString(L"进入了Mass初始化函数");
}

void UnderWaterComAlogrithm::QPSK_IPP_Va_Init()
{
    OutputDebugString(L"进入了QPSK得初始化函数，嘿嘿嘿\n");

    // Channel 1
    ippsZero_32f(Syn_SigIn_1_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 2
    ippsZero_32f(Syn_SigIn_2_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 3
    ippsZero_32f(Syn_SigIn_3_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 4
    ippsZero_32f(Syn_SigIn_4_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 5
    ippsZero_32f(Syn_SigIn_5_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 6
    ippsZero_32f(Syn_SigIn_6_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 7
    ippsZero_32f(Syn_SigIn_7_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 8
    ippsZero_32f(Syn_SigIn_8_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 9
    ippsZero_32f(Syn_SigIn_9_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 10
    ippsZero_32f(Syn_SigIn_10_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 11
    ippsZero_32f(Syn_SigIn_11_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 12
    ippsZero_32f(Syn_SigIn_12_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 13
    ippsZero_32f(Syn_SigIn_13_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 14
    ippsZero_32f(Syn_SigIn_14_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 15
    ippsZero_32f(Syn_SigIn_15_QPSK, QPSK_g_Syn_BufCnt);

    // Channel 16
    ippsZero_32f(Syn_SigIn_16_QPSK, QPSK_g_Syn_BufCnt);
}


//每个float传入8192个数据
float UnderWaterComAlogrithm::SC_FDE_DECODE(float* data1, float* data2, float* data3, float* data4, Ipp32fc* Signal_DataEqu, const char* BinaryData,
    Ipp32fc* Syn_DataCachePrmy_1_COPY,
    Ipp32fc* Syn_DataCachePrmy_2_COPY,
    Ipp32fc* Syn_DataCachePrmy_3_COPY,
    Ipp32fc* Syn_DataCachePrmy_4_COPY)
{
    Ipp32f* SignalOut_BP_1 = ippsMalloc_32f(g_Syn_BufCnt);
    Ipp32f* SignalOut_BP_2 = ippsMalloc_32f(g_Syn_BufCnt);
    Ipp32f* SignalOut_BP_3 = ippsMalloc_32f(g_Syn_BufCnt);
    Ipp32f* SignalOut_BP_4 = ippsMalloc_32f(g_Syn_BufCnt);

    DownConversion_BandPass(data1, g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS, Syn_FIRLen_BANDPASS,
        SignalOut_BP_1);
    MIMO_Syn_Edited(MaxCacheFrameCnt, Syn_StepCnt_1, Syn_DataCacheCnt_1, Syn_DataCache_1, Syn_DataCachePrmy_1, Sig_blk_1,
        SignalOut_BP_1, g_Syn_BufCnt,
        Syn_RefCopySam, Syn_RefCopyAll, &Syn_Flag_1, Syn_SigRec_1, Syn_Threshold,
        g_Syn_BufCnt, g_Syn_NFFT_RAW, g_Syn_BufSamCnt, g_SamStep, Signal_After_BP_lenth,
        g_LFM2Data_lenth, g_InfoSamPointTotalSyn, g_fs, DelayLen, Syn_Threshold, Syn_DataCachePrmy_1_COPY);



    DownConversion_BandPass(data2, g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS, Syn_FIRLen_BANDPASS,
        SignalOut_BP_2);
    MIMO_Syn_Edited(MaxCacheFrameCnt, Syn_StepCnt_2, Syn_DataCacheCnt_2, Syn_DataCache_2, Syn_DataCachePrmy_2, Sig_blk_2,
        SignalOut_BP_2, g_Syn_BufCnt,
        Syn_RefCopySam, Syn_RefCopyAll, &Syn_Flag_2, Syn_SigRec_2, Syn_Threshold,
        g_Syn_BufCnt, g_Syn_NFFT_RAW, g_Syn_BufSamCnt, g_SamStep, Signal_After_BP_lenth,
        g_LFM2Data_lenth, g_InfoSamPointTotalSyn, g_fs, DelayLen, Syn_Threshold, Syn_DataCachePrmy_2_COPY);




    DownConversion_BandPass(data3, g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS, Syn_FIRLen_BANDPASS,
        SignalOut_BP_3);
    MIMO_Syn_Edited(MaxCacheFrameCnt, Syn_StepCnt_3, Syn_DataCacheCnt_3, Syn_DataCache_3, Syn_DataCachePrmy_3, Sig_blk_3,
        SignalOut_BP_3, g_Syn_BufCnt,
        Syn_RefCopySam, Syn_RefCopyAll, &Syn_Flag_3, Syn_SigRec_3, Syn_Threshold,
        g_Syn_BufCnt, g_Syn_NFFT_RAW, g_Syn_BufSamCnt, g_SamStep, Signal_After_BP_lenth,
        g_LFM2Data_lenth, g_InfoSamPointTotalSyn, g_fs, DelayLen, Syn_Threshold, Syn_DataCachePrmy_3_COPY);



    DownConversion_BandPass(data4, g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS, Syn_FIRLen_BANDPASS,
        SignalOut_BP_4);
    MIMO_Syn_Edited(MaxCacheFrameCnt, Syn_StepCnt_4, Syn_DataCacheCnt_4, Syn_DataCache_4, Syn_DataCachePrmy_4, Sig_blk_4,
        SignalOut_BP_4, g_Syn_BufCnt,
        Syn_RefCopySam, Syn_RefCopyAll, &Syn_Flag_4, Syn_SigRec_4, Syn_Threshold,
        g_Syn_BufCnt, g_Syn_NFFT_RAW, g_Syn_BufSamCnt, g_SamStep, Signal_After_BP_lenth,
        g_LFM2Data_lenth, g_InfoSamPointTotalSyn, g_fs, DelayLen, Syn_Threshold, Syn_DataCachePrmy_4_COPY);


    ippsFree(SignalOut_BP_1);
    ippsFree(SignalOut_BP_2);
    ippsFree(SignalOut_BP_3);
    ippsFree(SignalOut_BP_4);

    if (Syn_Flag_1 && Syn_Flag_2 && Syn_Flag_3 && Syn_Flag_4)
    {
        OutputDebugString(L"太牛了啊，终于 进来了频域的同步啊啊啊啊啊。。。。。。\n");

        Ipp32fc* UWParts = ippsMalloc_32fc(g_N_Block * channel_num_CONST * N_g);
        Ipp32fc* DataParts = ippsMalloc_32fc(g_N_Block * channel_num_CONST * g_Syn_NFFT);

        MIMO_syn_dopl_baseband_Process_Edited(Syn_SigRec_1, Syn_SigRec_2, Syn_SigRec_3, Syn_SigRec_4,
            g_N_Block, UWParts, DataParts,
            N_g, g_Syn_NFFT, g_InfoSamPointTotalSyn, N_upsample, g_f0, g_fs, Syn_FIRLen);


        Ipp32fc* Symbol = ippsMalloc_32fc(g_N_Block * g_Syn_NFFT);
        Ipp32fc* BinaryUWArray = ippsMalloc_32fc(g_N_Block * N_g);
        ippsZero_32fc(BinaryUWArray, g_N_Block * N_g);
        for (int i = 0; i < g_N_Block; i++) {
            Ipp32fc* SymbolTemp = ippsMalloc_32fc(g_Syn_NFFT);
            ippsCopy_32fc(g_SymbolTxMatrix + i * (g_SymbolTxMatrix_len / g_N_Block), SymbolTemp, (g_SymbolTxMatrix_len / g_N_Block));
            ippsCopy_32fc(BinaryUWArray + i * N_g, SymbolTemp + (g_SymbolTxMatrix_len / g_N_Block), N_g);
            ippsCopy_32fc(SymbolTemp, Symbol + i * g_Syn_NFFT, g_Syn_NFFT);
            ippsFree(SymbolTemp);
        }
        Ipp32fc* h_Estimation = ippsMalloc_32fc(channel_num_CONST * N_g);
        // 信道估计 + PTR SIMO被动时间反转镜+再做一次SBL估计q+信道均衡，带分组相位纠正的FDE-NP

        MIMO_Mul_Process(channel_num_CONST, g_N_Block, BinaryUWArray, Symbol, g_SymbolTxMatrix, DataParts, UWParts,
            Signal_DataEqu, h_Estimation,
            g_Syn_NFFT, N_g, N_samp_SIMO, g_block_num
        );


        Ipp32fc* Signal_DataEqu_Out = ippsMalloc_32fc(g_N_AllBlockDataBit);
        Delete_Data_Equ_N_Samp(Signal_DataEqu, Signal_DataEqu_Out, g_Syn_NFFT, N_g, g_N_Block, N_samp_SIMO);


        // 硬判决
        Ipp32fc* DecisionSymbol = ippsMalloc_32fc(g_N_AllBlockDataBit);
        HardDecision(
            g_N_AllBlockDataBit,               // DecisionSymbolSoft 的长度
            Signal_DataEqu_Out, // 输入软判决符号数组
            Table,           // 调制表
            4,            // 调制表大小
            DecisionSymbol   // 输出硬判决符号数组
        );
        // 解映射
        Ipp8u* BitsAftDemaapping = ippsMalloc_8u((g_N_AllBlockDataBit * 2));
        Demapping(DecisionSymbol, g_N_AllBlockDataBit, Table, 4, BitsAftDemaapping);
        // 解交织
        Ipp8u* OutputBits = ippsMalloc_8u((g_N_AllBlockDataBit * 2));
        //Ipp32u* Sort_Table = ippsMalloc_32u((g_N_AllBlockDataBit * 2));
        int tableLength = (g_N_AllBlockDataBit * 2);
        //Load32uData("IPPS_Sort_Table.txt", Sort_Table, (g_N_AllBlockDataBit * 2));
        DeinterleaveBits(g_Sort_Table, tableLength, BitsAftDemaapping, OutputBits);
        // 维特比解码
        // 创建空字符串
        string encodedStr;
        // 遍历每个字节并转换为字符'0'或'1'
        for (int i = 0; i < (g_N_AllBlockDataBit * 2); ++i) {
            encodedStr += (OutputBits[i] == 0 ? '0' : '1'); // 根据字节值判断是'0'还是'1'
        }
        //这里开始是维特比解码
        const char* encoded_bits = encodedStr.c_str();
        char decodedBits[g_N_AllBlockDataBit + 1];//这里因为使用了字符串数组，所以最后要加上一位
        ViterbiDecode(encoded_bits, 7, 91, 121, decodedBits, sizeof(decodedBits));
        cout << "编码结果：" << endl << encodedStr << endl << "解码字符串长度为:" << endl << sizeof(decodedBits) << endl << "解码结果：" << endl << decodedBits << endl;
        ippsFree(UWParts);
        ippsFree(DataParts);
        ippsFree(Symbol);
        ippsFree(BinaryUWArray);
        ippsFree(h_Estimation);
        ippsFree(Signal_DataEqu_Out);
        ippsFree(DecisionSymbol);
        ippsFree(BitsAftDemaapping);
        ippsFree(OutputBits);
        float BER = calculateBER_IPP(BinaryData, decodedBits, g_N_AllBlockDataBit);
        IPP_Va_Init();//每次解码完成初始化传入的全局变量
        return BER;

    }

    return -1.0f;
}

float UnderWaterComAlogrithm::SF_SC_FDE_DECODE(float* data1, float* data2, float* data3, float* data4, Ipp32fc* Signal_DataEqu, const char* BinaryData,
    Ipp32fc* SF_Syn_DataCachePrmy_1_COPY,
    Ipp32fc* SF_Syn_DataCachePrmy_2_COPY,
    Ipp32fc* SF_Syn_DataCachePrmy_3_COPY,
    Ipp32fc* SF_Syn_DataCachePrmy_4_COPY)
{
    Ipp32f* SignalOut_BP_1 = ippsMalloc_32f(SF_g_Syn_BufCnt);
    Ipp32f* SignalOut_BP_2 = ippsMalloc_32f(SF_g_Syn_BufCnt);
    Ipp32f* SignalOut_BP_3 = ippsMalloc_32f(SF_g_Syn_BufCnt);
    Ipp32f* SignalOut_BP_4 = ippsMalloc_32f(SF_g_Syn_BufCnt);

    DownConversion_BandPass(data1, SF_g_Syn_BufCnt,
        SF_Syn_FIRCoe_SC_BANDPASS, SF_Syn_FIRLen_BANDPASS,
        SignalOut_BP_1);
    MIMO_Syn_Edited(SF_MaxCacheFrameCnt, SF_Syn_StepCnt_1, SF_Syn_DataCacheCnt_1, SF_Syn_DataCache_1, SF_Syn_DataCachePrmy_1, SF_Sig_blk_1,
        SignalOut_BP_1, SF_g_Syn_BufCnt,
        SF_Syn_RefCopySam, SF_Syn_RefCopyAll, &SF_Syn_Flag_1, SF_Syn_SigRec_1, SF_Syn_Threshold,
        SF_g_Syn_BufCnt, SF_g_Syn_NFFT_RAW, SF_g_Syn_BufSamCnt, SF_g_SamStep, SF_Signal_After_BP_lenth,
        SF_g_LFM2Data_lenth, SF_g_InfoSamPointTotalSyn, SF_g_fs, SF_DelayLen, SF_Syn_Threshold, SF_Syn_DataCachePrmy_1_COPY);

    DownConversion_BandPass(data2, SF_g_Syn_BufCnt,
        SF_Syn_FIRCoe_SC_BANDPASS, SF_Syn_FIRLen_BANDPASS,
        SignalOut_BP_2);
    MIMO_Syn_Edited(SF_MaxCacheFrameCnt, SF_Syn_StepCnt_2, SF_Syn_DataCacheCnt_2, SF_Syn_DataCache_2, SF_Syn_DataCachePrmy_2, SF_Sig_blk_2,
        SignalOut_BP_2, SF_g_Syn_BufCnt,
        SF_Syn_RefCopySam, SF_Syn_RefCopyAll, &SF_Syn_Flag_2, SF_Syn_SigRec_2, SF_Syn_Threshold,
        SF_g_Syn_BufCnt, SF_g_Syn_NFFT_RAW, SF_g_Syn_BufSamCnt, SF_g_SamStep, SF_Signal_After_BP_lenth,
        SF_g_LFM2Data_lenth, SF_g_InfoSamPointTotalSyn, SF_g_fs, SF_DelayLen, SF_Syn_Threshold, SF_Syn_DataCachePrmy_2_COPY);

    DownConversion_BandPass(data3, SF_g_Syn_BufCnt,
        SF_Syn_FIRCoe_SC_BANDPASS, SF_Syn_FIRLen_BANDPASS,
        SignalOut_BP_3);
    MIMO_Syn_Edited(SF_MaxCacheFrameCnt, SF_Syn_StepCnt_3, SF_Syn_DataCacheCnt_3, SF_Syn_DataCache_3, SF_Syn_DataCachePrmy_3, SF_Sig_blk_3,
        SignalOut_BP_3, SF_g_Syn_BufCnt,
        SF_Syn_RefCopySam, SF_Syn_RefCopyAll, &SF_Syn_Flag_3, SF_Syn_SigRec_3, SF_Syn_Threshold,
        SF_g_Syn_BufCnt, SF_g_Syn_NFFT_RAW, SF_g_Syn_BufSamCnt, SF_g_SamStep, SF_Signal_After_BP_lenth,
        SF_g_LFM2Data_lenth, SF_g_InfoSamPointTotalSyn, SF_g_fs, SF_DelayLen, SF_Syn_Threshold, SF_Syn_DataCachePrmy_3_COPY);

    DownConversion_BandPass(data4, SF_g_Syn_BufCnt,
        SF_Syn_FIRCoe_SC_BANDPASS, SF_Syn_FIRLen_BANDPASS,
        SignalOut_BP_4);
    MIMO_Syn_Edited(SF_MaxCacheFrameCnt, SF_Syn_StepCnt_4, SF_Syn_DataCacheCnt_4, SF_Syn_DataCache_4, SF_Syn_DataCachePrmy_4, SF_Sig_blk_4,
        SignalOut_BP_4, SF_g_Syn_BufCnt,
        SF_Syn_RefCopySam, SF_Syn_RefCopyAll, &SF_Syn_Flag_4, SF_Syn_SigRec_4, SF_Syn_Threshold,
        SF_g_Syn_BufCnt, SF_g_Syn_NFFT_RAW, SF_g_Syn_BufSamCnt, SF_g_SamStep, SF_Signal_After_BP_lenth,
        SF_g_LFM2Data_lenth, SF_g_InfoSamPointTotalSyn, SF_g_fs, SF_DelayLen, SF_Syn_Threshold, SF_Syn_DataCachePrmy_4_COPY);

    ippsFree(SignalOut_BP_1);
    ippsFree(SignalOut_BP_2);
    ippsFree(SignalOut_BP_3);
    ippsFree(SignalOut_BP_4);

    if (SF_Syn_Flag_1 && SF_Syn_Flag_2 && SF_Syn_Flag_3 && SF_Syn_Flag_4)
    {
        OutputDebugString(L"太帅了啊，终于进来了短帧的同步啊啊啊啊啊。。。。。。\n");

        Ipp32fc* UWParts = ippsMalloc_32fc(SF_g_N_Block * SF_channel_num_CONST * SF_N_g);
        Ipp32fc* DataParts = ippsMalloc_32fc(SF_g_N_Block * SF_channel_num_CONST * SF_g_Syn_NFFT);

        MIMO_syn_dopl_baseband_Process_Edited(SF_Syn_SigRec_1, SF_Syn_SigRec_2, SF_Syn_SigRec_3, SF_Syn_SigRec_4,
            SF_g_N_Block, UWParts, DataParts,
            SF_N_g, SF_g_Syn_NFFT, SF_g_InfoSamPointTotalSyn, SF_N_upsample, SF_g_f0, SF_g_fs, SF_Syn_FIRLen);

        Ipp32fc* Symbol = ippsMalloc_32fc(SF_g_N_Block * SF_g_Syn_NFFT);
        Ipp32fc* BinaryUWArray = ippsMalloc_32fc(SF_g_N_Block * SF_N_g);
        ippsZero_32fc(BinaryUWArray, SF_g_N_Block * SF_N_g);
        for (int i = 0; i < SF_g_N_Block; i++) {
            Ipp32fc* SymbolTemp = ippsMalloc_32fc(SF_g_Syn_NFFT);
            ippsCopy_32fc(SF_g_SymbolTxMatrix + i * (SF_g_SymbolTxMatrix_len / SF_g_N_Block), SymbolTemp, (SF_g_SymbolTxMatrix_len / SF_g_N_Block));
            ippsCopy_32fc(BinaryUWArray + i * SF_N_g, SymbolTemp + (SF_g_SymbolTxMatrix_len / SF_g_N_Block), SF_N_g);
            ippsCopy_32fc(SymbolTemp, Symbol + i * SF_g_Syn_NFFT, SF_g_Syn_NFFT);
            ippsFree(SymbolTemp);
        }
        Ipp32fc* h_Estimation = ippsMalloc_32fc(SF_channel_num_CONST * SF_N_g);
        // 信道估计 + PTR SIMO被动时间反转镜+再做一次SBL估计q+信道均衡，带分组相位纠正的FDE-NP

        MIMO_Mul_Process(SF_channel_num_CONST, SF_g_N_Block, BinaryUWArray, Symbol, SF_g_SymbolTxMatrix, DataParts, UWParts,
            Signal_DataEqu, h_Estimation,
            SF_g_Syn_NFFT, SF_N_g, SF_N_samp_SIMO, SF_g_block_num
        );

        Ipp32fc* Signal_DataEqu_Out = ippsMalloc_32fc(SF_g_N_AllBlockDataBit);
        Delete_Data_Equ_N_Samp(Signal_DataEqu, Signal_DataEqu_Out, SF_g_Syn_NFFT, SF_N_g, SF_g_N_Block, SF_N_samp_SIMO);

        // 硬判决
        Ipp32fc* DecisionSymbol = ippsMalloc_32fc(SF_g_N_AllBlockDataBit);
        HardDecision(
            SF_g_N_AllBlockDataBit,               // DecisionSymbolSoft 的长度
            Signal_DataEqu_Out, // 输入软判决符号数组
            SF_Table,           // 调制表
            4,            // 调制表大小
            DecisionSymbol   // 输出硬判决符号数组
        );
        // 解映射
        Ipp8u* BitsAftDemaapping = ippsMalloc_8u((SF_g_N_AllBlockDataBit * 2));
        Demapping(DecisionSymbol, SF_g_N_AllBlockDataBit, SF_Table, 4, BitsAftDemaapping);
        // 解交织
        Ipp8u* OutputBits = ippsMalloc_8u((SF_g_N_AllBlockDataBit * 2));
        int tableLength = (SF_g_N_AllBlockDataBit * 2);
        DeinterleaveBits(SF_g_Sort_Table, tableLength, BitsAftDemaapping, OutputBits);
        // 维特比解码
        string encodedStr;
        for (int i = 0; i < (SF_g_N_AllBlockDataBit * 2); ++i) {
            encodedStr += (OutputBits[i] == 0 ? '0' : '1');
        }
        const char* encoded_bits = encodedStr.c_str();
        char decodedBits[SF_g_N_AllBlockDataBit + 1];
        ViterbiDecode(encoded_bits, 7, 91, 121, decodedBits, sizeof(decodedBits));
        cout << "编码结果：" << endl << encodedStr << endl << "解码字符串长度为:" << endl << sizeof(decodedBits) << endl << "解码结果：" << endl << decodedBits << endl;

        ippsFree(UWParts);
        ippsFree(DataParts);
        ippsFree(Symbol);
        ippsFree(BinaryUWArray);
        ippsFree(h_Estimation);
        ippsFree(Signal_DataEqu_Out);
        ippsFree(DecisionSymbol);
        ippsFree(BitsAftDemaapping);
        ippsFree(OutputBits);

        SF_IPP_Va_Init();//每次解码完成初始化传入的全局变量
        float BER = calculateBER_IPP(BinaryData, decodedBits, SF_g_N_AllBlockDataBit);
        return BER;
    }

    return -1.0f;
}

void UnderWaterComAlogrithm::MASS_DECODE(float* data, float* channel_length, Ipp8u* Mass_BitsDecoded, Ipp32f* Syn2_CorrCur_Padded_Copy ,int* synFlag)
{
    Ipp32f* SignalOut_BP_MASS = ippsMalloc_32f(MA_g_Syn_BufCnt);

    DownConversion_BandPass(data, MA_g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS, Syn_FIRLen_BANDPASS,
        SignalOut_BP_MASS);
    MASS_Syn_Edited(MA_MaxCacheFrameCnt, Syn_StepCnt_MASS, Syn_DataCacheCnt_MASS, Syn_DataCache_MASS, Syn_DataCachePrmy_MASS, Sig_blk_MASS,
        SignalOut_BP_MASS, MA_g_Syn_BufCnt,
        MA_Syn_RefCopySam, MA_Syn_RefCopyAll, &Syn_Flag_MASS, Syn_SigRec_MASS, MA_Syn_Threshold,
        MA_g_Syn_BufCnt, MA_g_Syn_NFFT_RAW, MA_g_Syn_BufSamCnt, MA_g_SamStep, MA_Signal_After_BP_lenth,
        MA_g_LFM2Data_lenth, MA_g_InfoSamPointTotalSyn, MA_g_fs, MA_DelayLen, MA_Syn_Threshold, channel_length, Syn2_CorrCur_Padded_Copy);
    if (Syn_Flag_MASS)
    {
        OutputDebugString(L"太狠了啊，终于进来了扩频的同步啊啊啊啊啊。。。。。。\n");

        *synFlag = 1;
        Ipp32fc* Syn_SigRec_Cplx = ippsMalloc_32fc(MA_g_InfoSamPointTotalSyn);
        Rev2Cpl_SC(Syn_SigRec_MASS, MA_g_InfoSamPointTotalSyn, Syn_SigRec_Cplx);
        MassDecode(Syn_SigRec_Cplx, Mass_BitsDecoded, MA_g_f0, MA_g_fs);
        ippsFree(Syn_SigRec_Cplx);
        MASS_Init();
    }
    ippsFree(SignalOut_BP_MASS);
}

float UnderWaterComAlogrithm::SC_FDE_DECODE_6K8K(float* data1, float* data2, 
    float* data3, float* data4, 
    Ipp32fc* Signal_DataEqu, const char* BinaryData, 
    Ipp32fc* Syn_DataCachePrmy_1_COPY, 
    Ipp32fc* Syn_DataCachePrmy_2_COPY, 
    Ipp32fc* Syn_DataCachePrmy_3_COPY, 
    Ipp32fc* Syn_DataCachePrmy_4_COPY)
{
    Ipp32f* SignalOut_BP_1 = ippsMalloc_32f(g_Syn_BufCnt);
    Ipp32f* SignalOut_BP_2 = ippsMalloc_32f(g_Syn_BufCnt);
    Ipp32f* SignalOut_BP_3 = ippsMalloc_32f(g_Syn_BufCnt);
    Ipp32f* SignalOut_BP_4 = ippsMalloc_32f(g_Syn_BufCnt);

    DownConversion_BandPass(data1, g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS_6K8K, Syn_FIRLen_BANDPASS,
        SignalOut_BP_1);
    MIMO_Syn_Edited(MaxCacheFrameCnt, Syn_StepCnt_1, Syn_DataCacheCnt_1, Syn_DataCache_1, Syn_DataCachePrmy_1, Sig_blk_1,
        SignalOut_BP_1, g_Syn_BufCnt,
        Syn_RefCopySam_6K8K, Syn_RefCopyAll_6K8K, &Syn_Flag_1, Syn_SigRec_1, Syn_Threshold,
        g_Syn_BufCnt, g_Syn_NFFT_RAW, g_Syn_BufSamCnt, g_SamStep, Signal_After_BP_lenth,
        g_LFM2Data_lenth, g_InfoSamPointTotalSyn, g_fs, DelayLen, Syn_Threshold, Syn_DataCachePrmy_1_COPY);



    DownConversion_BandPass(data2, g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS_6K8K, Syn_FIRLen_BANDPASS,
        SignalOut_BP_2);
    MIMO_Syn_Edited(MaxCacheFrameCnt, Syn_StepCnt_2, Syn_DataCacheCnt_2, Syn_DataCache_2, Syn_DataCachePrmy_2, Sig_blk_2,
        SignalOut_BP_2, g_Syn_BufCnt,
        Syn_RefCopySam_6K8K, Syn_RefCopyAll_6K8K, &Syn_Flag_2, Syn_SigRec_2, Syn_Threshold,
        g_Syn_BufCnt, g_Syn_NFFT_RAW, g_Syn_BufSamCnt, g_SamStep, Signal_After_BP_lenth,
        g_LFM2Data_lenth, g_InfoSamPointTotalSyn, g_fs, DelayLen, Syn_Threshold, Syn_DataCachePrmy_2_COPY);




    DownConversion_BandPass(data3, g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS_6K8K, Syn_FIRLen_BANDPASS,
        SignalOut_BP_3);
    MIMO_Syn_Edited(MaxCacheFrameCnt, Syn_StepCnt_3, Syn_DataCacheCnt_3, Syn_DataCache_3, Syn_DataCachePrmy_3, Sig_blk_3,
        SignalOut_BP_3, g_Syn_BufCnt,
        Syn_RefCopySam_6K8K, Syn_RefCopyAll_6K8K, &Syn_Flag_3, Syn_SigRec_3, Syn_Threshold,
        g_Syn_BufCnt, g_Syn_NFFT_RAW, g_Syn_BufSamCnt, g_SamStep, Signal_After_BP_lenth,
        g_LFM2Data_lenth, g_InfoSamPointTotalSyn, g_fs, DelayLen, Syn_Threshold, Syn_DataCachePrmy_3_COPY);



    DownConversion_BandPass(data4, g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS_6K8K, Syn_FIRLen_BANDPASS,
        SignalOut_BP_4);
    MIMO_Syn_Edited(MaxCacheFrameCnt, Syn_StepCnt_4, Syn_DataCacheCnt_4, Syn_DataCache_4, Syn_DataCachePrmy_4, Sig_blk_4,
        SignalOut_BP_4, g_Syn_BufCnt,
        Syn_RefCopySam_6K8K, Syn_RefCopyAll_6K8K, &Syn_Flag_4, Syn_SigRec_4, Syn_Threshold,
        g_Syn_BufCnt, g_Syn_NFFT_RAW, g_Syn_BufSamCnt, g_SamStep, Signal_After_BP_lenth,
        g_LFM2Data_lenth, g_InfoSamPointTotalSyn, g_fs, DelayLen, Syn_Threshold, Syn_DataCachePrmy_4_COPY);


    ippsFree(SignalOut_BP_1);
    ippsFree(SignalOut_BP_2);
    ippsFree(SignalOut_BP_3);
    ippsFree(SignalOut_BP_4);

    if (Syn_Flag_1 && Syn_Flag_2 && Syn_Flag_3 && Syn_Flag_4)
    {
        OutputDebugString(L"太牛了啊，终于 进来了6K8K版本频域的同步啊啊啊啊啊。。。。。。\n");

        Ipp32fc* UWParts = ippsMalloc_32fc(g_N_Block * channel_num_CONST * N_g);
        Ipp32fc* DataParts = ippsMalloc_32fc(g_N_Block * channel_num_CONST * g_Syn_NFFT);

        MIMO_syn_dopl_baseband_Process_Edited(Syn_SigRec_1, Syn_SigRec_2, Syn_SigRec_3, Syn_SigRec_4,
            g_N_Block, UWParts, DataParts,
            N_g, g_Syn_NFFT, g_InfoSamPointTotalSyn, N_upsample, MQPSK_g_f0, g_fs, Syn_FIRLen);


        Ipp32fc* Symbol = ippsMalloc_32fc(g_N_Block * g_Syn_NFFT);
        Ipp32fc* BinaryUWArray = ippsMalloc_32fc(g_N_Block * N_g);
        ippsZero_32fc(BinaryUWArray, g_N_Block * N_g);
        for (int i = 0; i < g_N_Block; i++) {
            Ipp32fc* SymbolTemp = ippsMalloc_32fc(g_Syn_NFFT);
            ippsCopy_32fc(g_SymbolTxMatrix + i * (g_SymbolTxMatrix_len / g_N_Block), SymbolTemp, (g_SymbolTxMatrix_len / g_N_Block));
            ippsCopy_32fc(BinaryUWArray + i * N_g, SymbolTemp + (g_SymbolTxMatrix_len / g_N_Block), N_g);
            ippsCopy_32fc(SymbolTemp, Symbol + i * g_Syn_NFFT, g_Syn_NFFT);
            ippsFree(SymbolTemp);
        }
        Ipp32fc* h_Estimation = ippsMalloc_32fc(channel_num_CONST * N_g);
        // 信道估计 + PTR SIMO被动时间反转镜+再做一次SBL估计q+信道均衡，带分组相位纠正的FDE-NP

        MIMO_Mul_Process(channel_num_CONST, g_N_Block, BinaryUWArray, Symbol, g_SymbolTxMatrix, DataParts, UWParts,
            Signal_DataEqu, h_Estimation,
            g_Syn_NFFT, N_g, N_samp_SIMO, g_block_num
        );


        Ipp32fc* Signal_DataEqu_Out = ippsMalloc_32fc(g_N_AllBlockDataBit);
        Delete_Data_Equ_N_Samp(Signal_DataEqu, Signal_DataEqu_Out, g_Syn_NFFT, N_g, g_N_Block, N_samp_SIMO);


        // 硬判决
        Ipp32fc* DecisionSymbol = ippsMalloc_32fc(g_N_AllBlockDataBit);
        HardDecision(
            g_N_AllBlockDataBit,               // DecisionSymbolSoft 的长度
            Signal_DataEqu_Out, // 输入软判决符号数组
            Table,           // 调制表
            4,            // 调制表大小
            DecisionSymbol   // 输出硬判决符号数组
        );
        // 解映射
        Ipp8u* BitsAftDemaapping = ippsMalloc_8u((g_N_AllBlockDataBit * 2));
        Demapping(DecisionSymbol, g_N_AllBlockDataBit, Table, 4, BitsAftDemaapping);
        // 解交织
        Ipp8u* OutputBits = ippsMalloc_8u((g_N_AllBlockDataBit * 2));
        //Ipp32u* Sort_Table = ippsMalloc_32u((g_N_AllBlockDataBit * 2));
        int tableLength = (g_N_AllBlockDataBit * 2);
        //Load32uData("IPPS_Sort_Table.txt", Sort_Table, (g_N_AllBlockDataBit * 2));
        DeinterleaveBits(g_Sort_Table, tableLength, BitsAftDemaapping, OutputBits);
        // 维特比解码
        // 创建空字符串
        string encodedStr;
        // 遍历每个字节并转换为字符'0'或'1'
        for (int i = 0; i < (g_N_AllBlockDataBit * 2); ++i) {
            encodedStr += (OutputBits[i] == 0 ? '0' : '1'); // 根据字节值判断是'0'还是'1'
        }
        //这里开始是维特比解码
        const char* encoded_bits = encodedStr.c_str();
        char decodedBits[g_N_AllBlockDataBit + 1];//这里因为使用了字符串数组，所以最后要加上一位
        ViterbiDecode(encoded_bits, 7, 91, 121, decodedBits, sizeof(decodedBits));
        cout << "编码结果：" << endl << encodedStr << endl << "解码字符串长度为:" << endl << sizeof(decodedBits) << endl << "解码结果：" << endl << decodedBits << endl;
        ippsFree(UWParts);
        ippsFree(DataParts);
        ippsFree(Symbol);
        ippsFree(BinaryUWArray);
        ippsFree(h_Estimation);
        ippsFree(Signal_DataEqu_Out);
        ippsFree(DecisionSymbol);
        ippsFree(BitsAftDemaapping);
        ippsFree(OutputBits);
        float BER = calculateBER_IPP(BinaryData, decodedBits, g_N_AllBlockDataBit);
        IPP_Va_Init();//每次解码完成初始化传入的全局变量
        return BER;

    }

    return -1.0f;
}

float UnderWaterComAlogrithm::SF_SC_FDE_DECODE_6K8K(float* data1, float* data2, 
    float* data3, float* data4, 
    Ipp32fc* Signal_DataEqu, const char* BinaryData, 
    Ipp32fc* SF_Syn_DataCachePrmy_1_COPY, 
    Ipp32fc* SF_Syn_DataCachePrmy_2_COPY, 
    Ipp32fc* SF_Syn_DataCachePrmy_3_COPY, 
    Ipp32fc* SF_Syn_DataCachePrmy_4_COPY)
{
    Ipp32f* SignalOut_BP_1 = ippsMalloc_32f(SF_g_Syn_BufCnt);
    Ipp32f* SignalOut_BP_2 = ippsMalloc_32f(SF_g_Syn_BufCnt);
    Ipp32f* SignalOut_BP_3 = ippsMalloc_32f(SF_g_Syn_BufCnt);
    Ipp32f* SignalOut_BP_4 = ippsMalloc_32f(SF_g_Syn_BufCnt);

    DownConversion_BandPass(data1, SF_g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS_6K8K, SF_Syn_FIRLen_BANDPASS,
        SignalOut_BP_1);
    MIMO_Syn_Edited(SF_MaxCacheFrameCnt, SF_Syn_StepCnt_1, SF_Syn_DataCacheCnt_1, SF_Syn_DataCache_1, SF_Syn_DataCachePrmy_1, SF_Sig_blk_1,
        SignalOut_BP_1, SF_g_Syn_BufCnt,
        Syn_RefCopySam_6K8K, Syn_RefCopyAll_6K8K, &SF_Syn_Flag_1, SF_Syn_SigRec_1, SF_Syn_Threshold,
        SF_g_Syn_BufCnt, SF_g_Syn_NFFT_RAW, SF_g_Syn_BufSamCnt, SF_g_SamStep, SF_Signal_After_BP_lenth,
        SF_g_LFM2Data_lenth, SF_g_InfoSamPointTotalSyn, SF_g_fs, SF_DelayLen, SF_Syn_Threshold, SF_Syn_DataCachePrmy_1_COPY);

    DownConversion_BandPass(data2, SF_g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS_6K8K, SF_Syn_FIRLen_BANDPASS,
        SignalOut_BP_2);
    MIMO_Syn_Edited(SF_MaxCacheFrameCnt, SF_Syn_StepCnt_2, SF_Syn_DataCacheCnt_2, SF_Syn_DataCache_2, SF_Syn_DataCachePrmy_2, SF_Sig_blk_2,
        SignalOut_BP_2, SF_g_Syn_BufCnt,
        Syn_RefCopySam_6K8K, Syn_RefCopyAll_6K8K, &SF_Syn_Flag_2, SF_Syn_SigRec_2, SF_Syn_Threshold,
        SF_g_Syn_BufCnt, SF_g_Syn_NFFT_RAW, SF_g_Syn_BufSamCnt, SF_g_SamStep, SF_Signal_After_BP_lenth,
        SF_g_LFM2Data_lenth, SF_g_InfoSamPointTotalSyn, SF_g_fs, SF_DelayLen, SF_Syn_Threshold, SF_Syn_DataCachePrmy_2_COPY);

    DownConversion_BandPass(data3, SF_g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS_6K8K, SF_Syn_FIRLen_BANDPASS,
        SignalOut_BP_3);
    MIMO_Syn_Edited(SF_MaxCacheFrameCnt, SF_Syn_StepCnt_3, SF_Syn_DataCacheCnt_3, SF_Syn_DataCache_3, SF_Syn_DataCachePrmy_3, SF_Sig_blk_3,
        SignalOut_BP_3, SF_g_Syn_BufCnt,
        Syn_RefCopySam_6K8K, Syn_RefCopyAll_6K8K, &SF_Syn_Flag_3, SF_Syn_SigRec_3, SF_Syn_Threshold,
        SF_g_Syn_BufCnt, SF_g_Syn_NFFT_RAW, SF_g_Syn_BufSamCnt, SF_g_SamStep, SF_Signal_After_BP_lenth,
        SF_g_LFM2Data_lenth, SF_g_InfoSamPointTotalSyn, SF_g_fs, SF_DelayLen, SF_Syn_Threshold, SF_Syn_DataCachePrmy_3_COPY);

    DownConversion_BandPass(data4, SF_g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS_6K8K, SF_Syn_FIRLen_BANDPASS,
        SignalOut_BP_4);
    MIMO_Syn_Edited(SF_MaxCacheFrameCnt, SF_Syn_StepCnt_4, SF_Syn_DataCacheCnt_4, SF_Syn_DataCache_4, SF_Syn_DataCachePrmy_4, SF_Sig_blk_4,
        SignalOut_BP_4, SF_g_Syn_BufCnt,
        Syn_RefCopySam_6K8K, Syn_RefCopyAll_6K8K, &SF_Syn_Flag_4, SF_Syn_SigRec_4, SF_Syn_Threshold,
        SF_g_Syn_BufCnt, SF_g_Syn_NFFT_RAW, SF_g_Syn_BufSamCnt, SF_g_SamStep, SF_Signal_After_BP_lenth,
        SF_g_LFM2Data_lenth, SF_g_InfoSamPointTotalSyn, SF_g_fs, SF_DelayLen, SF_Syn_Threshold, SF_Syn_DataCachePrmy_4_COPY);

    ippsFree(SignalOut_BP_1);
    ippsFree(SignalOut_BP_2);
    ippsFree(SignalOut_BP_3);
    ippsFree(SignalOut_BP_4);

    if (SF_Syn_Flag_1 && SF_Syn_Flag_2 && SF_Syn_Flag_3 && SF_Syn_Flag_4)
    {
        OutputDebugString(L"太帅了啊，终于进来了6K8K版本短帧的同步啊啊啊啊啊。。。。。。\n");

        Ipp32fc* UWParts = ippsMalloc_32fc(SF_g_N_Block * SF_channel_num_CONST * SF_N_g);
        Ipp32fc* DataParts = ippsMalloc_32fc(SF_g_N_Block * SF_channel_num_CONST * SF_g_Syn_NFFT);

        MIMO_syn_dopl_baseband_Process_Edited(SF_Syn_SigRec_1, SF_Syn_SigRec_2, SF_Syn_SigRec_3, SF_Syn_SigRec_4,
            SF_g_N_Block, UWParts, DataParts,
            SF_N_g, SF_g_Syn_NFFT, SF_g_InfoSamPointTotalSyn, SF_N_upsample, MQPSK_g_f0, SF_g_fs, SF_Syn_FIRLen);

        Ipp32fc* Symbol = ippsMalloc_32fc(SF_g_N_Block * SF_g_Syn_NFFT);
        Ipp32fc* BinaryUWArray = ippsMalloc_32fc(SF_g_N_Block * SF_N_g);
        ippsZero_32fc(BinaryUWArray, SF_g_N_Block * SF_N_g);
        for (int i = 0; i < SF_g_N_Block; i++) {
            Ipp32fc* SymbolTemp = ippsMalloc_32fc(SF_g_Syn_NFFT);
            ippsCopy_32fc(SF_g_SymbolTxMatrix + i * (SF_g_SymbolTxMatrix_len / SF_g_N_Block), SymbolTemp, (SF_g_SymbolTxMatrix_len / SF_g_N_Block));
            ippsCopy_32fc(BinaryUWArray + i * SF_N_g, SymbolTemp + (SF_g_SymbolTxMatrix_len / SF_g_N_Block), SF_N_g);
            ippsCopy_32fc(SymbolTemp, Symbol + i * SF_g_Syn_NFFT, SF_g_Syn_NFFT);
            ippsFree(SymbolTemp);
        }
        Ipp32fc* h_Estimation = ippsMalloc_32fc(SF_channel_num_CONST * SF_N_g);
        // 信道估计 + PTR SIMO被动时间反转镜+再做一次SBL估计q+信道均衡，带分组相位纠正的FDE-NP

        MIMO_Mul_Process(SF_channel_num_CONST, SF_g_N_Block, BinaryUWArray, Symbol, SF_g_SymbolTxMatrix, DataParts, UWParts,
            Signal_DataEqu, h_Estimation,
            SF_g_Syn_NFFT, SF_N_g, SF_N_samp_SIMO, SF_g_block_num
        );

        Ipp32fc* Signal_DataEqu_Out = ippsMalloc_32fc(SF_g_N_AllBlockDataBit);
        Delete_Data_Equ_N_Samp(Signal_DataEqu, Signal_DataEqu_Out, SF_g_Syn_NFFT, SF_N_g, SF_g_N_Block, SF_N_samp_SIMO);

        // 硬判决
        Ipp32fc* DecisionSymbol = ippsMalloc_32fc(SF_g_N_AllBlockDataBit);
        HardDecision(
            SF_g_N_AllBlockDataBit,               // DecisionSymbolSoft 的长度
            Signal_DataEqu_Out, // 输入软判决符号数组
            SF_Table,           // 调制表
            4,            // 调制表大小
            DecisionSymbol   // 输出硬判决符号数组
        );
        // 解映射
        Ipp8u* BitsAftDemaapping = ippsMalloc_8u((SF_g_N_AllBlockDataBit * 2));
        Demapping(DecisionSymbol, SF_g_N_AllBlockDataBit, SF_Table, 4, BitsAftDemaapping);
        // 解交织
        Ipp8u* OutputBits = ippsMalloc_8u((SF_g_N_AllBlockDataBit * 2));
        int tableLength = (SF_g_N_AllBlockDataBit * 2);
        DeinterleaveBits(SF_g_Sort_Table, tableLength, BitsAftDemaapping, OutputBits);
        // 维特比解码
        string encodedStr;
        for (int i = 0; i < (SF_g_N_AllBlockDataBit * 2); ++i) {
            encodedStr += (OutputBits[i] == 0 ? '0' : '1');
        }
        const char* encoded_bits = encodedStr.c_str();
        char decodedBits[SF_g_N_AllBlockDataBit + 1];
        ViterbiDecode(encoded_bits, 7, 91, 121, decodedBits, sizeof(decodedBits));
        cout << "编码结果：" << endl << encodedStr << endl << "解码字符串长度为:" << endl << sizeof(decodedBits) << endl << "解码结果：" << endl << decodedBits << endl;

        ippsFree(UWParts);
        ippsFree(DataParts);
        ippsFree(Symbol);
        ippsFree(BinaryUWArray);
        ippsFree(h_Estimation);
        ippsFree(Signal_DataEqu_Out);
        ippsFree(DecisionSymbol);
        ippsFree(BitsAftDemaapping);
        ippsFree(OutputBits);

        SF_IPP_Va_Init();//每次解码完成初始化传入的全局变量
        float BER = calculateBER_IPP(BinaryData, decodedBits, SF_g_N_AllBlockDataBit);
        return BER;
    }

    return -1.0f;
}

void UnderWaterComAlogrithm::MASS_DECODE_6K8K(float* data, float* channel_length, 
    Ipp8u* Mass_BitsDecoded, Ipp32f* Syn2_CorrCur_Padded_Copy, int* synFlag)
{
    Ipp32f* SignalOut_BP_MASS = ippsMalloc_32f(MA_g_Syn_BufCnt);

    DownConversion_BandPass(data, MA_g_Syn_BufCnt,
        Syn_FIRCoe_SC_BANDPASS_6K8K, Syn_FIRLen_BANDPASS,
        SignalOut_BP_MASS);
    MASS_Syn_Edited(MA_MaxCacheFrameCnt, Syn_StepCnt_MASS, Syn_DataCacheCnt_MASS, Syn_DataCache_MASS, Syn_DataCachePrmy_MASS, Sig_blk_MASS,
        SignalOut_BP_MASS, MA_g_Syn_BufCnt,
        Syn_RefCopySam_6K8K, Syn_RefCopyAll_6K8K, &Syn_Flag_MASS, Syn_SigRec_MASS, MA_Syn_Threshold,
        MA_g_Syn_BufCnt, MA_g_Syn_NFFT_RAW, MA_g_Syn_BufSamCnt, MA_g_SamStep, MA_Signal_After_BP_lenth,
        MA_g_LFM2Data_lenth, MA_g_InfoSamPointTotalSyn, MA_g_fs, MA_DelayLen, MA_Syn_Threshold, channel_length, Syn2_CorrCur_Padded_Copy);
    if (Syn_Flag_MASS)
    {
        OutputDebugString(L"太狠了啊，终于进来了6K8K版本扩频的同步啊啊啊啊啊。。。。。。\n");

        *synFlag = 1;
        Ipp32fc* Syn_SigRec_Cplx = ippsMalloc_32fc(MA_g_InfoSamPointTotalSyn);
        Rev2Cpl_SC(Syn_SigRec_MASS, MA_g_InfoSamPointTotalSyn, Syn_SigRec_Cplx);
        MassDecode(Syn_SigRec_Cplx, Mass_BitsDecoded, MQPSK_g_f0, g_fs);
        ippsFree(Syn_SigRec_Cplx);
        MASS_Init();
    }
    ippsFree(SignalOut_BP_MASS);
}


void UnderWaterComAlogrithm::My_GenerateQPSKSignal_Wrapper(
    // 输入参数 - 常量部分
    Ipp32f fs,                    // 采样频率
    Ipp32f f0_1,                  // 载波频率
    Ipp32f f0_2,                  // 载波频率
    Ipp32f R_s1,                  // 有效符号速率
    Ipp32f alpha_1,               // 滚降系数
    Ipp32s M,                     // 调制阶数
    Ipp32s bitnum_per,            // 每符号比特数
    Ipp32f Sym_time,              // 有效符号持续时间
    Ipp32s Numburst,              // 突发数量
    Ipp32s Numblock_perburst,     // 每突发块数

    // 输入参数 - 线性调频信号
    Ipp32f* sig_syn_LFM_1,        // 线性调频信号
    Ipp32f* sig_syn_LFM_2,        // 线性调频信号
    Ipp32s syn_length,            // 线性调频信号长度

    Ipp32f* p_1,                 // 根升余弦滤波器系数
    Ipp32s p_1_length,            // 根升余弦滤波器长度

    const char* filename, int N, int& data_size, Ipp32f* signal_send_1, Ipp32f* signal_send_2, int* output_length)
{
    GenerateQPSKSignal_Wrapper(// 输入参数 - 常量部分
        fs,                    // 采样频率
        f0_1,                  // 载波频率
        f0_2,                  // 载波频率
        R_s1,                  // 有效符号速率
        alpha_1,               // 滚降系数
        M,                     // 调制阶数
        bitnum_per,            // 每符号比特数
        Sym_time,              // 有效符号持续时间
        Numburst,              // 突发数量
        Numblock_perburst,     // 每突发块数

        // 输入参数 - 线性调频信号
        sig_syn_LFM_1,        // 线性调频信号
        sig_syn_LFM_2,        // 线性调频信号
        syn_length,            // 线性调频信号长度

        p_1,                 // 根升余弦滤波器系数
        p_1_length,            // 根升余弦滤波器长度

        filename, N, data_size, signal_send_1, signal_send_2, output_length);
}


void UnderWaterComAlogrithm::MDFE_DECODE(float* data1, float* data2, float* data3, float* data4,
    float* data5, float* data6, float* data7, float* data8,
    float* data9, float* data10, float* data11, float* data12,
    float* data13, float* data14, float* data15, float* data16,

    Ipp32fc* Syn_DataCachePrmy_COPY,
    Ipp32fc* va_Syn_FIRCoe_SC_BANDPASS_QPSK, Ipp32s va_Syn_FIRLen_BANDPASS_QPSK,
    Ipp32fc* va_Syn_RefCopySam, Ipp32fc* va_Syn_RefCopyAll,
    Ipp32u va_MQPSK_f0,
    int va_n1, int va_n2, float va_Delta, float va_Lambda, float va_PLL1, float va_PLL2,
    Ipp32u va_MaxCacheFrameCnt_QPSK, Ipp32f va_Syn_Threshold_QPSK, QPSK_Channel* channels, Ipp8u* va_BitsAftDemaapping,
    bool* decode_completed_flag , bool decode_enable_flag, Ipp32fc* x_zheng_without_train_seq)
{
    //OutputDebugString(L"进入了MDFE_Decode解码函数，开始第一个循环");
    Ipp32f* SignalOut_BP[MQPSK_channel_num];
    for (int i = 0; i < MQPSK_channel_num; i++) {
        SignalOut_BP[i] = ippsMalloc_32f(QPSK_g_Syn_BufCnt);

    }
    float* input_data[MQPSK_channel_num] = {
        data1, data2, data3, data4, data5, data6, data7, data8,
        data9, data10, data11, data12, data13, data14, data15, data16
    };
    //OutputDebugString(L"进入了MDFE第二个循环");
    
    for (int i = 0; i < MQPSK_channel_num; i++)
    {

        DownConversion_BandPass(input_data[i], QPSK_g_Syn_BufCnt,
            va_Syn_FIRCoe_SC_BANDPASS_QPSK, va_Syn_FIRLen_BANDPASS_QPSK,
            SignalOut_BP[i]);
        MIMO_Syn_Edited(MaxCacheFrameCnt_QPSK, channels[i].Syn_StepCnt, channels[i].Syn_DataCacheCnt, channels[i].Syn_DataCache, channels[i].Syn_DataCachePrmy, channels[i].Sig_blk,
            SignalOut_BP[i], QPSK_g_Syn_BufCnt,
            va_Syn_RefCopySam, va_Syn_RefCopyAll, &channels[i].Syn_Flag, channels[i].Syn_SigRec, Syn_Threshold_QPSK,
            QPSK_g_Syn_BufCnt, QPSK_g_Syn_NFFT_RAW, QPSK_g_Syn_BufSamCnt, QPSK_g_SamStep, QPSK_Signal_After_BP_lenth,
            QPSK_g_LFM2Data_lenth, QPSK_g_InfoSamPointTotalSyn, MQPSK_fs, QPSK_DelayLen, Syn_Threshold_QPSK, Syn_DataCachePrmy_COPY);
    }


    //OutputDebugString(L"进入了MDFE第三个循环");

    for (int i = 0; i < MQPSK_channel_num; i++) {

        if (SignalOut_BP[i]) {
            ippsFree(SignalOut_BP[i]);
        }
    }

    //OutputDebugString(L"进入了MDFE第四个循环");

   /* bool allSet = true;
    for (int i = 0; i < MQPSK_channel_num; i++) {

        if (channels[i].Syn_Flag != 1) {
            allSet = false;
            break;
        }
    }*/

    if (decode_enable_flag)
    {
        OutputDebugString(L"至少有一个通道已经同步了\r\n");
        Ipp32fc* MQPSK_p_1_COMPLEX = ippsMalloc_32fc(MQPSK_p_1_length);
        ippsZero_32fc(MQPSK_p_1_COMPLEX, MQPSK_p_1_length);
        Rev2Cpl_SC(MQPSK_p_1, MQPSK_p_1_length, MQPSK_p_1_COMPLEX);

        Ipp32fc* SignalAftDownSam = ippsMalloc_32fc(MQPSK_channel_num * MQPSK_Numsym_perblock * 2);
        ippsZero_32fc(SignalAftDownSam, MQPSK_channel_num * MQPSK_Numsym_perblock * 2);
        // 循环处理所有通道，直接写入目标数组
        //OutputDebugString(L"进入了MDFE第五个循环");

        for (int i = 0; i < MQPSK_channel_num; i++) {

            DownConversion_QPSK(channels[i].Syn_SigRec, QPSK_g_InfoSamPointTotalSyn,
                MQPSK_p_1_COMPLEX, MQPSK_p_1_length,
                SignalAftDownSam + i * MQPSK_Numsym_perblock * 2,  // 直接写入目标位置
                va_MQPSK_f0, MQPSK_fs, N_pn / 2);
        }


        OutputDebugString(L"检测到allSet为真，开始调用MDFE_HX_64f");


        Ipp32fc* x_zheng = ippsMalloc_32fc(MQPSK_R_s1 * 10);
        ippsZero_32fc(x_zheng, MQPSK_R_s1 * 10);
        MDFE_HX_64f(
            MQPSK_channel_num,
            train_sequence,
            Table,
            TDE_Table_size,
            SignalAftDownSam,
            MQPSK_channel_num * MQPSK_Numsym_perblock * 2,
            va_n1,
            va_n2,
            va_Delta,
            va_Lambda,
            va_PLL1,
            va_PLL2,
            MQPSK_Numsym_perblock * 2,
            QPSK_Bitnum_per,
            QPSK_N_Samp,
            x_zheng
        );

        OutputDebugString(L"调用MDFE_HX_64f结束，开始调用HardDecision");

        //Ipp32fc* x_zheng_without_train_seq = ippsMalloc_32fc(MQPSK_data_length / 2);
        //ippsZero_32fc(x_zheng_without_train_seq, MQPSK_data_length / 2);
        ippsCopy_32fc(x_zheng + train_sequence_len, x_zheng_without_train_seq, MQPSK_data_length / 2);
        // 硬判决
        Ipp32fc* DecisionSymbol = ippsMalloc_32fc(MQPSK_data_length / 2);
        HardDecision(
            MQPSK_data_length / 2,               // DecisionSymbolSoft 的长度
            x_zheng_without_train_seq, // 输入软判决符号数组
            Table,           // 调制表
            4,            // 调制表大小
            DecisionSymbol   // 输出硬判决符号数组
        );

        OutputDebugString(L"调用HardDecision结束，开始调用Demapping");

        // 解映射
        Demapping(DecisionSymbol, MQPSK_data_length / 2, Table, 4, va_BitsAftDemaapping);

        OutputDebugString(L"调用Demapping结束");


        if (decode_completed_flag != nullptr) {
            *decode_completed_flag = true;
        }
        // 释放内存
        ippsFree(SignalAftDownSam);
        ippsFree(x_zheng);
        ippsFree(DecisionSymbol);
        ippsFree(MQPSK_p_1_COMPLEX);
    }


}

float UnderWaterComAlogrithm::My_Calculate_BER_AND_SAVE_IMG(Ipp8u* BitsAftDemaapping_1, Ipp8u* BitsAftDemaapping_2, const char* file_name, Ipp8u va_MQPSK_N, Ipp8u va_MQPSK_data_length)
{
    return Calculate_BER_AND_SAVE_IMG(BitsAftDemaapping_1, BitsAftDemaapping_2, file_name, va_MQPSK_N, va_MQPSK_data_length);
}

void UnderWaterComAlogrithm::QPSK_Channel_Init(QPSK_Channel* channel)
{
    if (channel == nullptr) return;

    // 分配内存
    channel->Syn_StepCnt = ippsMalloc_8u(sizeof(Ipp8u));
    channel->Syn_DataCacheCnt = ippsMalloc_8u(sizeof(Ipp8u));
    channel->Syn_DataCache = ippsMalloc_32fc(QPSK_g_Syn_BufCnt * (MaxCacheFrameCnt_QPSK + 2));
    channel->Syn_DataCachePrmy = ippsMalloc_32fc(QPSK_g_Syn_BufCnt * (MaxCacheFrameCnt_QPSK + 2));
    channel->Sig_blk = ippsMalloc_32fc(QPSK_g_Syn_NFFT_RAW);
    channel->Syn_SigRec = ippsMalloc_32f(QPSK_g_InfoSamPointTotalSyn);

    // 初始化数据
    channel->Syn_Flag = 0;
    if (channel->Syn_StepCnt) *channel->Syn_StepCnt = 0;
    if (channel->Syn_DataCacheCnt) ippsZero_8u(channel->Syn_DataCacheCnt, sizeof(Ipp8u));
    if (channel->Syn_DataCache) ippsZero_32fc(channel->Syn_DataCache, QPSK_g_Syn_BufCnt * (MaxCacheFrameCnt_QPSK + 2));
    if (channel->Syn_DataCachePrmy) ippsZero_32fc(channel->Syn_DataCachePrmy, QPSK_g_Syn_BufCnt * (MaxCacheFrameCnt_QPSK + 2));
    if (channel->Sig_blk) ippsZero_32fc(channel->Sig_blk, QPSK_g_Syn_NFFT_RAW);
    if (channel->Syn_SigRec) ippsZero_32f(channel->Syn_SigRec, QPSK_g_InfoSamPointTotalSyn);
}

void UnderWaterComAlogrithm::QPSK_Channel_Free(QPSK_Channel* channel)
{
    if (channel == nullptr) return;

    if (channel->Syn_StepCnt) {
        ippsFree(channel->Syn_StepCnt);
        channel->Syn_StepCnt = nullptr;
    }
    if (channel->Syn_DataCacheCnt) {
        ippsFree(channel->Syn_DataCacheCnt);
        channel->Syn_DataCacheCnt = nullptr;
    }
    if (channel->Syn_DataCache) {
        ippsFree(channel->Syn_DataCache);
        channel->Syn_DataCache = nullptr;
    }
    if (channel->Syn_DataCachePrmy) {
        ippsFree(channel->Syn_DataCachePrmy);
        channel->Syn_DataCachePrmy = nullptr;
    }
    if (channel->Sig_blk) {
        ippsFree(channel->Sig_blk);
        channel->Sig_blk = nullptr;
    }
    if (channel->Syn_SigRec) {
        ippsFree(channel->Syn_SigRec);
        channel->Syn_SigRec = nullptr;
    }
}

void UnderWaterComAlogrithm::MyLoadCharData(const char* filename, char* data, int length)
{
    LoadCharData(filename, data, length);
}

void UnderWaterComAlogrithm::My_ippsZero_32fc(Ipp32fc* pDst, int len)
{
    ippsZero_32fc(pDst, len);
}

void UnderWaterComAlogrithm::My_ippsZero_32f(Ipp32f* pDst, int len)
{
    ippsZero_32f(pDst, len);

}

void UnderWaterComAlogrithm::My_ippsZero_8u(Ipp8u* pDst, int len)
{
    ippsZero_8u(pDst, len);
}

Ipp8u* UnderWaterComAlogrithm::My_ippsMalloc_8u(int len)
{
    return ippsMalloc_8u(len);
}

Ipp32fc* UnderWaterComAlogrithm::My_ippsMalloc_32fc(int len)
{
    return ippsMalloc_32fc(len);
}

Ipp32f* UnderWaterComAlogrithm::My_ippsMalloc_32f(int len)
{
    return ippsMalloc_32f(len);
}

void UnderWaterComAlogrithm::My_ippsFree(void* ptr)
{
    ippsFree(ptr);
}
    
bool UnderWaterComAlogrithm::GetExePath(char* filepath, const int& max_length)
{
    auto sz = GetModuleFileNameA(nullptr, filepath, max_length);
    if (sz == 0)
        return false;
    for (int n = sz - 1; n > 0; n--) {
        if (filepath[n] == TCHAR('\\')) {
            filepath[n + 1] = 0;
            break;
        }
    }
    return true;
}




